#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
AI语音助手Web应用
基于Flask框架的Web版本
"""

import os
import json
import logging
import base64
import io
import ssl
from flask import Flask, render_template, request, jsonify
from flask_socketio import SocketIO, emit
from voice_assistant import VoiceAssistant
from simple_tts_service import SimpleTTSService

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# 创建Flask应用
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ai_voice_assistant_secret_key'

# 创建SocketIO实例
socketio = SocketIO(app, cors_allowed_origins="*")

# 全局语音助手实例
voice_assistant = None

def init_voice_assistant():
    """初始化语音助手"""
    global voice_assistant
    try:
        voice_assistant = VoiceAssistant()
        logger.info("语音助手初始化成功")
        return True
    except Exception as e:
        logger.error(f"语音助手初始化失败: {e}")
        return False

@app.route('/')
def index():
    """主页"""
    return render_template('index.html')

@app.route('/api/status')
def get_status():
    """获取服务状态"""
    global voice_assistant
    if voice_assistant is None:
        return jsonify({
            'status': 'error',
            'message': '语音助手未初始化'
        })
    
    return jsonify({
        'status': 'success',
        'message': '服务正常运行',
        'services': {
            'asr': 'ready',
            'llm': 'ready', 
            'tts': 'ready'
        }
    })

@app.route('/api/test', methods=['GET', 'POST'])
def test_ai_services():
    """测试AI服务"""
    global voice_assistant
    if voice_assistant is None:
        return jsonify({
            'status': 'error',
            'message': '语音助手未初始化'
        })
    
    try:
        # 使用默认测试音频文件
        test_audio_file = "test_1.pcm"
        if not os.path.exists(test_audio_file):
            return jsonify({
                'status': 'error',
                'message': f'测试音频文件 {test_audio_file} 不存在'
            })
        
        # 处理音频文件：ASR + LLM + TTS
        transcribed_text, ai_response = voice_assistant.process_audio_file(test_audio_file)
        
        # 生成语音合成
        audio_data = voice_assistant.synthesize_speech(
            text=ai_response,
            voice="xiaoyan",
            speed=50,
            volume=50,
            pitch=50
        )
        
        if audio_data:
            # 将音频数据转换为base64
            audio_base64 = base64.b64encode(audio_data).decode('utf-8')
            
            return jsonify({
                'status': 'success',
                'message': 'AI服务测试成功',
                'data': {
                    'transcribed_text': transcribed_text,
                    'ai_response': ai_response,
                    'audio_data': audio_base64,
                    'audio_format': 'pcm',
                    'sample_rate': 16000
                }
            })
        else:
            return jsonify({
                'status': 'error',
                'message': '语音合成失败'
            })
            
    except Exception as e:
        logger.error(f"AI服务测试失败: {e}")
        return jsonify({
            'status': 'error',
            'message': f'AI服务测试失败: {str(e)}'
        })

@socketio.on('connect')
def handle_connect():
    """处理客户端连接"""
    logger.info(f"客户端连接: {request.sid}")
    emit('status', {'message': '连接成功', 'status': 'connected'})

@socketio.on('disconnect')
def handle_disconnect():
    """处理客户端断开连接"""
    logger.info(f"客户端断开连接: {request.sid}")

@socketio.on('start_conversation')
def handle_start_conversation():
    """开始对话"""
    global voice_assistant
    logger.info("开始对话")
    
    if voice_assistant is None:
        emit('error', {'message': '语音助手未初始化'})
        return
    
    try:
        # 使用默认测试音频文件
        test_audio_file = "test_1.pcm"
        if not os.path.exists(test_audio_file):
            emit('error', {'message': f'测试音频文件 {test_audio_file} 不存在'})
            return
        
        # 发送处理状态
        emit('status', {'message': '正在处理音频...', 'status': 'processing'})
        
        # 处理音频文件：ASR + LLM + TTS
        transcribed_text, ai_response = voice_assistant.process_audio_file(test_audio_file)
        
        # 发送转写结果
        emit('transcription', {
            'text': transcribed_text,
            'status': 'completed'
        })
        
        # 发送AI回答
        emit('ai_response', {
            'text': ai_response,
            'status': 'completed'
        })
        
        # 生成语音合成
        emit('status', {'message': '正在生成语音...', 'status': 'synthesizing'})
        
        audio_data = voice_assistant.synthesize_speech(
            text=ai_response,
            voice="xiaoyan",
            speed=50,
            volume=50,
            pitch=50
        )
        
        if audio_data:
            # 将音频数据转换为base64
            audio_base64 = base64.b64encode(audio_data).decode('utf-8')
            
            # 发送音频数据
            emit('audio_data', {
                'data': audio_base64,
                'format': 'pcm',
                'sample_rate': 16000,
                'status': 'completed'
            })
            
            # 发送完成状态
            emit('status', {'message': '对话完成', 'status': 'completed'})
        else:
            emit('error', {'message': '语音合成失败'})
            
    except Exception as e:
        logger.error(f"对话处理失败: {e}")
        emit('error', {'message': f'对话处理失败: {str(e)}'})

@socketio.on('send_text')
def handle_text_message(data):
    """处理文本消息"""
    global voice_assistant
    text = data.get('text', '')
    logger.info(f"收到文本消息: {text}")
    
    if voice_assistant is None:
        emit('error', {'message': '语音助手未初始化'})
        return
    
    try:
        # 发送处理状态
        emit('status', {'message': '正在处理文本...', 'status': 'processing'})
        
        # 处理文本输入
        ai_response = voice_assistant.process_text_input(text, stream=False)
        
        # 发送AI回答
        emit('ai_response', {
            'text': ai_response,
            'status': 'completed'
        })
        
        # 生成语音合成
        emit('status', {'message': '正在生成语音...', 'status': 'synthesizing'})
        
        audio_data = voice_assistant.synthesize_speech(
            text=ai_response,
            voice="xiaoyan",
            speed=50,
            volume=50,
            pitch=50
        )
        
        if audio_data:
            # 将音频数据转换为base64
            audio_base64 = base64.b64encode(audio_data).decode('utf-8')
            
            # 发送音频数据
            emit('audio_data', {
                'data': audio_base64,
                'format': 'pcm',
                'sample_rate': 16000,
                'status': 'completed'
            })
            
            # 发送完成状态
            emit('status', {'message': '处理完成', 'status': 'completed'})
        else:
            emit('error', {'message': '语音合成失败'})
            
    except Exception as e:
        logger.error(f"文本处理失败: {e}")
        emit('error', {'message': f'文本处理失败: {str(e)}'})

@app.route('/api/upload_audio', methods=['POST'])
def upload_audio():
    """HTTP音频上传接口"""
    global voice_assistant
    logger.info("收到HTTP音频上传")
    
    if voice_assistant is None:
        return jsonify({'error': '语音助手未初始化'}), 500
    
    try:
        # 检查是否有音频文件
        if 'audio' not in request.files:
            return jsonify({'error': '没有音频文件'}), 400
        
        audio_file = request.files['audio']
        if audio_file.filename == '':
            return jsonify({'error': '没有选择文件'}), 400
        
        # 保存临时音频文件
        temp_audio_file = f"temp_audio_http_{request.remote_addr}.webm"
        audio_file.save(temp_audio_file)
        
        logger.info(f"音频文件已保存: {temp_audio_file}")
        
        # 处理音频文件：ASR + LLM + TTS
        transcribed_text, ai_response = voice_assistant.process_audio_file(temp_audio_file)
        
        # 生成语音合成
        audio_data = voice_assistant.synthesize_speech(
            text=ai_response,
            voice="xiaoyan",
            speed=50,
            volume=50,
            pitch=50
        )
        
        result = {
            'transcription': transcribed_text,
            'ai_response': ai_response,
            'status': 'completed'
        }
        
        if audio_data:
            # 将音频数据转换为base64
            audio_base64 = base64.b64encode(audio_data).decode('utf-8')
            result['audio_data'] = audio_base64
            result['sample_rate'] = 16000
            result['format'] = 'pcm'
        
        # 清理临时文件
        if os.path.exists(temp_audio_file):
            os.remove(temp_audio_file)
        
        logger.info("HTTP音频处理完成")
        return jsonify(result)
        
    except Exception as e:
        logger.error(f"HTTP音频处理失败: {e}")
        return jsonify({'error': f'音频处理失败: {str(e)}'}), 500

@socketio.on('upload_audio')
def handle_audio_upload(data):
    """处理音频上传"""
    global voice_assistant
    logger.info("收到音频上传")
    
    if voice_assistant is None:
        emit('error', {'message': '语音助手未初始化'})
        return
    
    try:
        # 获取音频数据
        audio_data = data.get('audio_data', '')
        if not audio_data:
            emit('error', {'message': '音频数据为空'})
            return
        
        # 解码base64音频数据
        audio_bytes = base64.b64decode(audio_data)
        
        # 保存临时音频文件
        temp_audio_file = f"temp_audio_{request.sid}.pcm"
        with open(temp_audio_file, 'wb') as f:
            f.write(audio_bytes)
        
        # 发送处理状态
        emit('status', {'message': '正在处理音频...', 'status': 'processing'})
        
        # 处理音频文件：ASR + LLM + TTS
        transcribed_text, ai_response = voice_assistant.process_audio_file(temp_audio_file)
        
        # 发送转写结果
        emit('transcription', {
            'text': transcribed_text,
            'status': 'completed'
        })
        
        # 发送AI回答
        emit('ai_response', {
            'text': ai_response,
            'status': 'completed'
        })
        
        # 生成语音合成
        emit('status', {'message': '正在生成语音...', 'status': 'synthesizing'})
        
        audio_data = voice_assistant.synthesize_speech(
            text=ai_response,
            voice="xiaoyan",
            speed=50,
            volume=50,
            pitch=50
        )
        
        if audio_data:
            # 将音频数据转换为base64
            audio_base64 = base64.b64encode(audio_data).decode('utf-8')
            
            # 发送音频数据
            emit('audio_data', {
                'data': audio_base64,
                'format': 'pcm',
                'sample_rate': 16000,
                'status': 'completed'
            })
            
            # 发送完成状态
            emit('status', {'message': '对话完成', 'status': 'completed'})
        else:
            emit('error', {'message': '语音合成失败'})
        
        # 清理临时文件
        if os.path.exists(temp_audio_file):
            os.remove(temp_audio_file)
            
    except Exception as e:
        logger.error(f"音频处理失败: {e}")
        emit('error', {'message': f'音频处理失败: {str(e)}'})

if __name__ == '__main__':
    # 初始化语音助手
    if init_voice_assistant():
        logger.info("启动Web应用...")
        
        # 检查SSL证书文件
        logger.info("未发现SSL证书，启动HTTP服务...")
        logger.info("HTTP访问地址:")
        logger.info("  - http://localhost:5000")
        logger.info("  - http://127.0.0.1:5000")
        logger.info("  - http://192.168.0.106:5000")
        logger.info("  - http://192.168.0.101:5000")
        logger.info("注意: HTTP模式下无法使用麦克风，需要HTTPS")

        # 启动HTTP服务
        socketio.run(app,
                    host='0.0.0.0',
                    port=5000,
                    debug=True,
                    allow_unsafe_werkzeug=True)
    else:
        logger.error("语音助手初始化失败，无法启动Web应用")
